package com.oa.admin.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.joneying.common.annotation.CommonService;
import com.joneying.common.web.response.Resp;
import com.oa.admin.dto.HouseAddDTO;
import com.oa.admin.dto.HouseCheckDTO;
import com.oa.admin.dto.HouseConditionDTO;
import com.oa.admin.dto.HouseUpdateDTO;
import com.oa.admin.entity.HouseCheckRecording;
import com.oa.admin.exportvo.HouseExportVO;
import com.oa.admin.service.IHouseCheckRecordingService;
import com.oa.admin.vo.HouseCheckRecordingDetailsVO;
import com.oa.admin.vo.HouseDetailsVO;
import com.oa.admin.vo.HouseListVO;
import com.oa.core.PageResult;
import com.oa.admin.entity.House;
import com.oa.admin.mapper.HouseMapper;
import com.oa.admin.service.IHouseService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.oa.core.constant.Constant;
import com.oa.core.enumm.CodeEnum;
import com.oa.core.exception.BusinessException;
import com.oa.core.exception.DataIsEmptyException;
import com.oa.core.utils.DateUtil;
import com.oa.core.utils.ExcelUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.plugins.Page;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

import static com.oa.core.utils.Validate.validate;

/**
 * <p>
 * 房屋表 服务实现类
 * </p>
 *
 * @author syb123
 * @since 2019-01-22
 */
@Service
public class HouseServiceImpl extends ServiceImpl<HouseMapper, House> implements IHouseService {

    private final HouseMapper houseMapper;
    private final IHouseCheckRecordingService houseCheckRecordingService;
    @Autowired
    private HttpServletResponse response;


    @Autowired
    public HouseServiceImpl(HouseMapper houseMapper, IHouseCheckRecordingService houseCheckRecordingService) {
        this.houseMapper = houseMapper;
        this.houseCheckRecordingService = houseCheckRecordingService;
    }

    @Override
    @CommonService
    public PageResult<House> findList(Integer pageNum, Integer pageSize) {
        if (pageNum == null) {
            List<House> list = houseMapper.findList();
            return new PageResult<>(list);
        } else {
            // 当前页，总条数 构造 page 对象
            Page<House> page = new Page<>(pageNum, pageSize);
            //查询
            List<House> list = houseMapper.findList(page);
            return new PageResult<>(list);
        }
    }

    /**
     * 根据id查询
     */
    @Override
    @CommonService
    public House findHouseById(String id) {
        return houseMapper.findById(id);
    }

    /**
     * 新增房屋
     *
     * @param houseAddDTO
     * @return
     */
    @Override
    @CommonService
    @Transactional
    public Resp addHouse(HouseAddDTO houseAddDTO) throws BusinessException {

        CheckoutParam(houseAddDTO);

        House house = new House();
        BeanUtils.copyProperties(houseAddDTO, house);

        try {
            insert(house);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("新增房屋失败!");
        }

        List<HouseCheckDTO> houseCheckDTOList = houseAddDTO.getHouseCheckDTOList();
        //入住记录
        if (CollUtil.isNotEmpty(houseCheckDTOList)) {
            List<HouseCheckRecording> houseCheckRecordingList = new ArrayList<>();
            houseCheckDTOList.forEach(x -> {
                HouseCheckRecording houseCheckRecording = new HouseCheckRecording();
                BeanUtils.copyProperties(x, houseCheckRecording);
                houseCheckRecording.setHouseId(house.getId());
                houseCheckRecordingList.add(houseCheckRecording);

            });
            try {
                houseCheckRecordingService.insertBatch(houseCheckRecordingList);
            } catch (Exception e) {
                e.printStackTrace();
                throw new BusinessException("添加入住记录失败!");
            }
        }

        return new Resp<String>().success("新增房屋成功!");
    }

    /**
     * 根据条件查询房屋列表
     *
     * @param houseConditionDTO
     * @return
     */
    @Override
    @CommonService
    public PageResult findHouseListByCondition(HouseConditionDTO houseConditionDTO) throws DataIsEmptyException {

        if (StringUtils.isEmpty(houseConditionDTO.getPage())) {
            List<HouseListVO> houseListVOList = houseMapper.findHouseListByCondition(houseConditionDTO);
            if (CollUtil.isEmpty(houseListVOList)) {
                throw new DataIsEmptyException();
            }
            return new PageResult<>(houseListVOList);
        } else {
            Page<House> page = new Page<>(houseConditionDTO.getPage(), houseConditionDTO.getLimit());
            List<HouseListVO> houseListVOList = houseMapper.findHouseListByCondition(page, houseConditionDTO);
            if (CollUtil.isEmpty(houseListVOList)) {
                throw new DataIsEmptyException();
            }
            return new PageResult<>(houseListVOList);
        }


    }

    /**
     * 根据主键id查询房屋详情
     *
     * @param id
     * @return
     */
    @Override
    @CommonService
    public Resp findHouseDetailsById(String id) {

        HouseDetailsVO houseDetailsVO = new HouseDetailsVO();
        List<HouseCheckRecordingDetailsVO> houseCheckRecordingDetailsVOList = new ArrayList<>();

        House house = houseMapper.findById(id);

        BeanUtils.copyProperties(house, houseDetailsVO);

        houseDetailsVO.setUses(houseDetailsVO.getUses().equals("1") ? "办公" : "宿舍");


        List<HouseCheckRecording> houseCheckRecordingList = houseCheckRecordingService.selectList(new EntityWrapper<HouseCheckRecording>().eq("is_deleted", Constant.IS_DELETE_NO).eq("house_id", house.getId()));
        if (CollUtil.isNotEmpty(houseCheckRecordingList)) {
            houseCheckRecordingList.forEach(x -> {
                HouseCheckRecordingDetailsVO houseCheckRecordingDetailsVO = new HouseCheckRecordingDetailsVO();
                BeanUtils.copyProperties(x, houseCheckRecordingDetailsVO);
                houseCheckRecordingDetailsVOList.add(houseCheckRecordingDetailsVO);
            });
        }

        houseDetailsVO.setHouseCheckRecordingDetailsVOList(houseCheckRecordingDetailsVOList);

        return new Resp<HouseDetailsVO>().success(houseDetailsVO);
    }

    /**
     * 根据主键id编辑房屋信息
     *
     * @param houseUpdateDTO
     * @return
     */
    @Override
    @CommonService
    @Transactional
    public Resp updateHouseDetailsById(HouseUpdateDTO houseUpdateDTO) throws BusinessException {

        CheckoutParamUpdatehouse(houseUpdateDTO, houseUpdateDTO.getHouseCheckRecordingList());

        House house = new House();

        BeanUtils.copyProperties(houseUpdateDTO, house);

        try {
            houseMapper.updateById(house);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("修改房屋信息失败!");
        }

        //入住记录
        List<HouseCheckRecording> houseCheckRecordingList = houseCheckRecordingService.selectList(new EntityWrapper<HouseCheckRecording>().eq("is_deleted", Constant.IS_DELETE_NO).
                eq("house_id", house.getId()));
        if (CollUtil.isNotEmpty(houseCheckRecordingList)) {
            houseCheckRecordingList.forEach(x -> {
                houseCheckRecordingService.deleteById(x.getId());
            });
        }

        List<HouseCheckRecording> checkRecordingList = houseUpdateDTO.getHouseCheckRecordingList();
        if (CollUtil.isNotEmpty(checkRecordingList)) {
            try {
                houseCheckRecordingService.insertBatch(checkRecordingList);
            } catch (Exception e) {
                e.printStackTrace();
                throw new BusinessException("修改房屋入住记录失败!");
            }
        }

        return new Resp<String>().success("修改房屋信息成功!");
    }

    /**
     * 根据主键id删除房屋信息
     *
     * @param id
     * @return
     */
    @Override
    @CommonService
    @Transactional
    public Resp deleteHouseDetailsById(String id) throws BusinessException {

        House house = houseMapper.findById(id);

        house.setIsDeleted(1);

        try {
            houseMapper.updateById(house);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("删除房屋信息失败!");
        }

        //入住记录
        List<HouseCheckRecording> houseCheckRecordingList = houseCheckRecordingService.selectList(new EntityWrapper<HouseCheckRecording>().eq("is_deleted", Constant.IS_DELETE_NO).
                eq("house_id", house.getId()));
        if (CollUtil.isNotEmpty(houseCheckRecordingList)) {
            houseCheckRecordingList.forEach(x -> {
                x.setIsDeleted(1);
            });

            try {
                houseCheckRecordingService.updateBatchById(houseCheckRecordingList);
            } catch (Exception e) {
                e.printStackTrace();
                throw new BusinessException("删除房屋入住记录失败!");
            }
        }
        return new Resp<String>().success("删除房屋信息成功!");
    }

    /**
     * 导出房屋租赁列表
     *
     * @return
     */
    @Override
    @CommonService
    public Resp exportHouseList() throws DataIsEmptyException, BusinessException {

        List<HouseListVO> houseListVOList = houseMapper.findHouseListByCondition(null);
        if (CollUtil.isNotEmpty(houseListVOList)) {
            List<HouseExportVO> houseExportVOS = new ArrayList<>();
            houseListVOList.forEach(x -> {
                HouseExportVO houseExportVO = new HouseExportVO();
                BeanUtils.copyProperties(x, houseExportVO);
                houseExportVOS.add(houseExportVO);
            });

            String[] rowName = {"房屋编号", "租赁时间", "到期时间", "提醒时间", "房屋地址", "用途"};

            try {
                ExcelUtil.downloadExcel("房屋租赁表" + DateUtil.getDayMonth(), rowName, houseExportVOS, "房屋租赁表" + DateUtil.getDayMonth() + ".xls", response);
            } catch (Exception e) {
                e.printStackTrace();
                throw new BusinessException("导出房屋租赁excel表格失败!");
            }

            return new Resp<>().success("导出房屋租赁excel表格成功!");
        }


        throw new DataIsEmptyException();
    }

    @Override
    public boolean deleteHouse(String id) {
        House house = new House();
        house.setId(id);
        house.setIsDeleted(1);
        if(updateById(house)){
            HouseCheckRecording houseCheckRecording = new HouseCheckRecording();
            houseCheckRecording.setIsDeleted(1);
            if(houseCheckRecordingService.update(houseCheckRecording, new EntityWrapper<HouseCheckRecording>().eq("house_id", id))){
                return true;
            }
        }
        return false;
    }

    /**
     * 参数校验--添加房屋
     *
     * @param
     */
    public void CheckoutParam(HouseAddDTO houseAddDTO) throws BusinessException {
        if (!StringUtils.isEmpty(houseAddDTO)) {
            List<String> validate = validate(houseAddDTO);
            if (CollUtil.isNotEmpty(validate)) {
                throw new BusinessException(CodeEnum.PARAMETERS_OF_THE_ABNORMAL.getCode(), validate.toString());
            }
        }
    }

    /**
     * 参数校验--修改房屋
     *
     * @param
     */
    public void CheckoutParamUpdatehouse(HouseUpdateDTO houseUpdateDTO, List<HouseCheckRecording> checkRecordingList) throws BusinessException {

        if (!StringUtils.isEmpty(houseUpdateDTO)) {
            List<String> validate = validate(houseUpdateDTO);
            if (CollUtil.isNotEmpty(validate)) {
                throw new BusinessException(CodeEnum.PARAMETERS_OF_THE_ABNORMAL.getCode(), validate.toString());
            }
        }

        if (CollUtil.isNotEmpty(checkRecordingList)) {
            List<String> processNodeDTOListValidate = new ArrayList<>();
            checkRecordingList.forEach(p -> {
                List<String> validate = validate(p);
                processNodeDTOListValidate.addAll(validate);
            });
            if (CollUtil.isNotEmpty(processNodeDTOListValidate)) {
                throw new BusinessException(CodeEnum.PARAMETERS_OF_THE_ABNORMAL.getCode(), processNodeDTOListValidate.toString());
            }
        }

    }
}
